package org.wattdepot.cli.command;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.client.WattDepotClientException;
import org.wattdepot.resource.source.jaxb.Source;

/**
 * Creates the SourcesCommand command handler.
 * @author Yichi Xu
 *
 */
public class SourcesCommand extends WattDepotCliCommand {

  /**
   * Creates an instance of the Sources command handler.
   * 
   * @param client An instance of the WattDepotClient.
   */
  public SourcesCommand(WattDepotClient client) {
    super(client);
  }

  /**
   * Performs the command.
   * @param command The command to process.
   * @return the result of the command.
   */
  @Override
  public String doCommand(String command) {
    StringTokenizer tokenizer = new StringTokenizer(command);
    List<String> tokens = new ArrayList<String>();
    while (tokenizer.hasMoreTokens()) {
      tokens.add(tokenizer.nextToken());
    }
    
    if (!"sources".equals(tokens.get(0))) {
      return WattDepotCliCommand.reportUnknownCommand(command);
    }
    
    if (tokens.size() != 1) {
      return this.reportError(PARAMETER_COUNT_ERROR);
    }
    
    try {
      return this.listSources();
    }
    catch (Exception ex) {
      return this.reportError(CONNECTION_ERROR);
    }
  }

  /**
   * get source parent given source.
   * 
   * @param source the source need to find its parent
   * @param parentList list of source that contains subsource
   * @return parent the parent of the given source
   * @throws WattDepotClientException Exception.
   */
  private String getSourceParent(List<Source> parentList, Source source)
      throws WattDepotClientException {
    String parentName = "";
    
    for (Source parent : parentList) {
      if (parent.getSubSources().toString().contains(source.getName())) {
        parentName = parent.getName();
      }
    }
    
    return parentName;
  }

  /**
   * generates the message contain information of all the sources available on the server.
   * 
   * @return message that contains all the source information.
   * @throws WattDepotClientException The exception.
   */
  private String listSources() throws WattDepotClientException {
    List<Source> parentList = new ArrayList<Source>();
    List<Source> sourceList = client.getSources();
    
    for (Source source : sourceList) {
      if (source.getSubSources() != null) {
        parentList.add(source);
      }
    }
    
    String format = " %1$-20s %2$-20s %3$-50s \n";
    String message = String.format(format, "Name", "Parent", "Description");
    StringBuffer buf = new StringBuffer();
    buf.append(message);
    
    for (Source source : sourceList) {
      String tempString =
          String.format(format, source.getName(), getSourceParent(parentList, source), source
              .getDescription());
      buf.append(tempString);
    }
    
    return buf.toString();
  }
  
  /**
   * Gets the help string associated with the Sources command.
   * 
   * @see org.wattdepot.cli.command.WattDepotCliCommand#getHelp()
   * @return Information on how to invoke the sources command.
   */
  @Override
  public String getHelp() {
    return "sources\n"
      + "  Prints a table summarizing the public sources in the system, one per line.\n";
  }
}
